package com.studyweb.service.impl;

import com.studyweb.service.VerificationCodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.security.SecureRandom;
import java.util.concurrent.TimeUnit;

/**
 * 验证码服务实现类
 * 
 * @author StudyWeb Team
 * @since 1.0.0
 */
@Slf4j
@Service
public class VerificationCodeServiceImpl implements VerificationCodeService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String CODE_PREFIX = "verification_code:";
    private static final SecureRandom random = new SecureRandom();

    /**
     * 生成6位数字验证码
     * 
     * @return String 验证码
     */
    @Override
    public String generateCode() {
        int code = 100000 + random.nextInt(900000);
        return String.valueOf(code);
    }

    /**
     * 存储验证码到Redis
     * 
     * @param email 邮箱地址
     * @param code 验证码
     * @param expireMinutes 过期时间（分钟）
     * @return boolean 存储是否成功
     */
    @Override
    public boolean storeCode(String email, String code, int expireMinutes) {
        try {
            String key = CODE_PREFIX + email;
            redisTemplate.opsForValue().set(key, code, expireMinutes, TimeUnit.MINUTES);
            log.info("验证码存储成功，邮箱：{}，过期时间：{}分钟", email, expireMinutes);
            return true;
        } catch (Exception e) {
            log.error("验证码存储失败，邮箱：{}，错误：{}", email, e.getMessage(), e);
            return false;
        }
    }

    /**
     * 验证验证码
     * 
     * @param email 邮箱地址
     * @param code 用户输入的验证码
     * @return boolean 验证是否通过
     */
    @Override
    public boolean verifyCode(String email, String code) {
        try {
            if (!StringUtils.hasText(email) || !StringUtils.hasText(code)) {
                return false;
            }

            String key = CODE_PREFIX + email;
            String storedCode = redisTemplate.opsForValue().get(key);
            
            if (storedCode != null && storedCode.equals(code)) {
                log.info("验证码验证成功，邮箱：{}", email);
                return true;
            } else {
                log.warn("验证码验证失败，邮箱：{}，输入的验证码：{}", email, code);
                return false;
            }
        } catch (Exception e) {
            log.error("验证码验证异常，邮箱：{}，错误：{}", email, e.getMessage(), e);
            return false;
        }
    }

    /**
     * 清除验证码
     * 
     * @param email 邮箱地址
     * @return boolean 清除是否成功
     */
    @Override
    public boolean clearCode(String email) {
        try {
            String key = CODE_PREFIX + email;
            Boolean deleted = redisTemplate.delete(key);
            log.info("验证码清除{}，邮箱：{}", deleted ? "成功" : "失败", email);
            return Boolean.TRUE.equals(deleted);
        } catch (Exception e) {
            log.error("验证码清除异常，邮箱：{}，错误：{}", email, e.getMessage(), e);
            return false;
        }
    }

    /**
     * 检查验证码是否存在
     * 
     * @param email 邮箱地址
     * @return boolean 验证码是否存在且未过期
     */
    @Override
    public boolean hasCode(String email) {
        try {
            String key = CODE_PREFIX + email;
            Boolean exists = redisTemplate.hasKey(key);
            return Boolean.TRUE.equals(exists);
        } catch (Exception e) {
            log.error("检查验证码存在性异常，邮箱：{}，错误：{}", email, e.getMessage(), e);
            return false;
        }
    }

    /**
     * 获取验证码剩余有效时间
     * 
     * @param email 邮箱地址
     * @return long 剩余有效时间（秒），-1表示不存在或已过期
     */
    @Override
    public long getCodeTtl(String email) {
        try {
            String key = CODE_PREFIX + email;
            Long ttl = redisTemplate.getExpire(key, TimeUnit.SECONDS);
            return ttl != null ? ttl : -1;
        } catch (Exception e) {
            log.error("获取验证码TTL异常，邮箱：{}，错误：{}", email, e.getMessage(), e);
            return -1;
        }
    }
}